﻿using UnityEngine;
using System.Collections;

namespace edu.wpi.cs.Project1
{
    /// <summary>
    /// The behaviour of the game ball.
    /// </summary>
    public class BallBehaviour : MonoBehaviour
    {
        /// <summary>
        /// The main script.
        /// </summary>
        private ARPhysicsGameBehaviour game;

        /// <summary>
        /// The name of the last collided game collider object as a workaround
        /// for adding many points to the score instead of just one.
        /// </summary>
        private string lastColliderName;

        /// <summary>
        /// Indicates whether the splitting has occured or not. Splitting should
        /// just occure once per round.
        /// </summary>
        private static bool splitted = false;

        /// <summary>
        /// The number of balls, so the main game is just notified about end of round when
        /// the last ball left the screen or hitted the 
        /// </summary>
        private static int ballsCount;

        void Awake()
        {
            ballsCount = 1;
        }

        /// <summary>
        /// Initializes the ball.
        /// </summary>
        void Start()
        {
            game = Camera.main.GetComponent<ARPhysicsGameBehaviour>();
            lastColliderName = string.Empty;
        }

        /// <summary>
        /// Updates the ball per frame.
        /// </summary>
        void Update()
        {
            Vector3 ballPos = Camera.main.WorldToViewportPoint(this.transform.position);
            if (ballPos.x < 0 || ballPos.x > 1 || ballPos.y < 0)
            {
                if (ballsCount == 1)
                {
                    splitted = false;
                    game.EndRound();
                }

                ballsCount--;
                Destroy(this.gameObject);

            }
        }

        /// <summary>
        /// Called when a new collision was detected
        /// </summary>
        /// <param name="other">The other collider</param>
        void OnCollisionEnter(Collision collision)
        {
            GameObject other = collision.collider.gameObject;

            
            if (other.tag.Equals("Finish"))
            {
                hit(100);
                if (ballsCount == 1)
                {
                    game.EndRound();
                }
                ballsCount--;
                Destroy(this.gameObject);
            }
            else if (other.tag.Equals("GameCollider"))
            {
                if (!other.name.Equals(lastColliderName))
                {
                    if (other.name.Equals("SimpleCollider"))
                    {
                        hit(10);
                    }
                    else if (other.name.Equals("SpinCollider") || other.name.Equals("BlinkCollider"))
                    {
                        hit(30);
                    }
                    else if (other.name.Equals("ForceCollider"))
                    {
                        hit(20);
                        this.gameObject.rigidbody.AddForce(other.transform.up.normalized * 2500, ForceMode.Impulse);

                    }
                    else if (other.name.Equals("SplitCollider"))
                    {
                        hit(10);
                        if (!splitted)
                        {
                            GameObject ball = Utility.CreateBall("Ball", this.gameObject.transform.position, Quaternion.identity);
                            splitted = true;
                            ballsCount = 2;
                        }
                    }

                    // save last collider name so that not two collisions with the same collider are possible.
                    lastColliderName = other.name;
                }
            }
        }

        /// <summary>
        /// Updates the score and creates a popup text.
        /// </summary>
        /// <param name="score">The score of the hit.</param>
        private void hit(int score)
        {
            game.ChangeScore(score);
            Utility.CreatePopupText(this.transform.localPosition, score.ToString());
        }
    }
}
